package com.ruoyi.web.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ChatUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.AiRequire;
import com.ruoyi.system.domain.AiScheme;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.IAiRequireService;
import com.ruoyi.system.service.IAiSchemeService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.service.ChatBankService;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户方案信息-对外API接口请求处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/api/scheme")
public class ApiAiSchemeController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(ApiAiSchemeController.class);
    @Autowired
    private IAiSchemeService schemeService;
    @Autowired
    private IAiRequireService requireService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ChatBankService chatBankService;

    @GetMapping(value = "/{id}")
    @ApiOperation(value = "根据方案ID获取信息详情")
    public AjaxResult getById(@PathVariable("id") Long id) {
        AiScheme scheme = schemeService.selectAiSchemeById(id);
        if (null == scheme) return AjaxResult.success();
        AiSchemeDetailVo resp = new AiSchemeDetailVo();
        BeanUtil.copyProperties(scheme, resp);
        SysUser sysUser = sysUserService.selectUserById(scheme.getUserId());
        if (null != sysUser) {
            resp.setUser(new SysUserVo(sysUser.getUserId(), sysUser.getNickName(), sysUser.getAvatar()));
        }
        // 方案关联的商机列表
        AiRequire require = new AiRequire();
        require.setSchemeId(scheme.getId());
        List<AiRequire> requireList = requireService.selectAiRequireList(require);
        if (CollUtil.isNotEmpty(requireList)) {
            resp.setRequireList(requireList.stream().map(this::changeRequireItem).collect(Collectors.toList()));
        }
        return AjaxResult.success(resp);
    }

    /**
     * 新增用户方案信息
     */
    @Log(title = "用户方案", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@RequestBody AiScheme aiScheme) {
        aiScheme.setUserId(getUserId());
        return toAjax(schemeService.insertAiScheme(aiScheme));
    }

    @Transactional
    @Log(title = "【AI生成商机】", businessType = BusinessType.INSERT)
    @PostMapping(value = "/gpt")
    @ApiOperation(value = "新增方案信息通过fast-gpt生成商机内容")
    public AjaxResult gpt(@RequestBody AiSchemeReqVo req) {
        // 调用fast-gpt，根据方案内容，分析产生商机内容，有则保存
        AiScheme scheme = schemeService.selectAiSchemeById(req.getSchemeId());
        if (null == scheme || !scheme.getUserId().equals(getUserId())) {
            return AjaxResult.error("方案信息不存在");
        }
        // 构建请求体, 通过方案，调用fast-gpt生成商机信息
        Map<String, Object> data = new HashMap<>();
        data.put("chatId", "");
        data.put("stream", false);
        data.put("detail", false);
        List<Map<String, Object>> messages = new ArrayList<>();
        messages.add(ChatUtils.message("user", scheme.getContent()));
        data.put("messages", messages);

        // 对于fast-gpt返回的content, 是否能转成JSON，能则解析用户的商机，保存下来，否则不管
        ChatUtils.Require schemeRequire = ChatUtils.requestChatRequire(data);
        if (null == schemeRequire) {
            return AjaxResult.error(HttpStatus.NOT_CREATE_SCHEME, "未生成商机");
        }

        // 否则保存方案商机信息
        String sessionId = IdUtils.fastUUID();
        String topicId = StringUtils.randomStr(8);
        String background = schemeRequire.getBackground();
        for (ChatUtils.RequireDetail requireDetail : schemeRequire.getChildren()) {
            AiRequire aiRequire = new AiRequire();
            aiRequire.setUserId(getUserId());
            aiRequire.setSchemeId(req.getSchemeId());
            aiRequire.setSessionId(sessionId);
            aiRequire.setTopicId(topicId);
            aiRequire.setTitle(requireDetail.getTitle());
            aiRequire.setBackground(background);
            aiRequire.setTarget(requireDetail.getTarget());
            aiRequire.setRequirement(requireDetail.getReq());
            aiRequire.setResponsibility(requireDetail.getResp());
            aiRequire.setTags(requireDetail.getTags());
            aiRequire.setInitFlag("0"); // 初始化标识：0-初始化，1-正常。默认由方案生成的内容是状态：初始化，后期通过定时任务完善
            requireService.insertAiRequire(aiRequire);

            log.info("======================");
            // 完善商机信息-异步执行
            chatBankService.requestFillChatRequire(aiRequire);
        }
        return AjaxResult.success(1);
    }

    @GetMapping(value = "/list")
    @ApiOperation(value = "根据状态status,sessionId,topicId条件, 获取当前用户的方案列表")
    public AjaxResult list(@RequestParam(value = "status", required = false) String status,
                           @RequestParam(value = "sessionId", required = false) String sessionId,
                           @RequestParam(value = "topicId", required = false) String topicId,
                           @RequestParam(value = "current", required = false) Long current,
                           @RequestParam(value = "size", required = false) Long size) {
        AiScheme scheme = new AiScheme();
        scheme.setSessionId(sessionId);
        scheme.setTopicId(topicId);
        scheme.setStatus(status);
        scheme.setUserId(getUserId());
        Map<String, Object> params = new HashMap<>();
        params.put("page", SqlUtil.getLimit(current, size));
        scheme.setParams(params);
        List<AiScheme> list = schemeService.selectAiSchemeList(scheme);
        if (CollUtil.isEmpty(list)) return AjaxResult.success(new ArrayList<>());
        return AjaxResult.success(list.stream().map(this::changeItem).collect(Collectors.toList()));
    }

    @GetMapping(value = "/case/list")
    @ApiOperation(value = "获取推荐方案(案例)列表")
    public AjaxResult caseList(@RequestParam(value = "current", required = false) Long current,
                               @RequestParam(value = "size", required = false) Long size) {
        AiScheme scheme = new AiScheme();
        scheme.setType("sys"); // 案例，查询系统推荐
        Map<String, Object> params = new HashMap<>();
        params.put("page", SqlUtil.getLimit(current, size));
        scheme.setParams(params);
        List<AiScheme> list = schemeService.selectAiSchemeList(scheme);
        if (CollUtil.isEmpty(list)) return AjaxResult.success(new ArrayList<>());
        return AjaxResult.success(list.stream().map(this::changeCaseItem).collect(Collectors.toList()));
    }

    private AiSchemeVo changeItem(AiScheme scheme) {
        AiSchemeVo resp = new AiSchemeVo();
        BeanUtil.copyProperties(scheme, resp);
        SysUser sysUser = sysUserService.selectUserById(scheme.getUserId());
        if (null != sysUser) {
            resp.setUser(new SysUserVo(sysUser.getUserId(), sysUser.getNickName(), sysUser.getAvatar()));
        }
        return resp;
    }

    private AiSchemeCaseVo changeCaseItem(AiScheme scheme) {
        AiSchemeCaseVo resp = new AiSchemeCaseVo();
        if (scheme.getStatus().equalsIgnoreCase("1")) {
            resp.setStatusName("进行中");
        } else if (scheme.getStatus().equalsIgnoreCase("2")) {
            resp.setStatusName("已完成");
        } else if (scheme.getStatus().equalsIgnoreCase("3")) {
            resp.setStatusName("已失败");
        }
        BeanUtil.copyProperties(scheme, resp);
        return resp;
    }

    private AiRequireVo changeRequireItem(AiRequire require) {
        AiRequireVo resp = new AiRequireVo();
        BeanUtil.copyProperties(require, resp);
        SysUser sysUser = sysUserService.selectUserById(require.getUserId());
        if (null != sysUser) {
            resp.setUser(new SysUserVo(sysUser.getUserId(), sysUser.getNickName(), sysUser.getAvatar()));
        }
        return resp;
    }
}
